home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Information / Programming / Stuart's Tech Notes / Sample AppleTalk adev / adev.c next >
Encoding:
C/C++ Source or Header  |  1995-10-29  |  4.8 KB  |  134 lines  |  [TEXT/KAHL]

  1. // Sample AppleTalk adev resource
  2. // (C) 1994-1995 Stuart Cheshire <cheshire@cs.stanford.edu>
  3. //
  4. // You need to contact Apple to get an adev id assigned.
  5. // This file must be compiled into a code resource of type 'adev' with your id.
  6. // This resource file is then merged into the final adev file built by the
  7. // atlk project (See atlk.c)
  8. // 
  9. // The main routine in assembly code here calls the three C routines below:
  10. // 1. doGetAdev indicates the available AppleTalk connection icons to display in
  11. // the Network Control Panel There is just one for the 'None' connection, but
  12. // other adevs may offer multiple connections -- eg. multiple serial ports --
  13. // in which case they are distinguished by an index in the low byte of d2
  14. // 2. doSelAdev is called when the user selects our icon
  15. // 3. doReSelAdev  is called when the user double-clicks on our icon
  16. // Some of the parameters to the C routines are declared volatile to provide
  17. // call-by-value-return semantics, to allow the C code to easily return values
  18. // in registers without having to use even more nasty inline assembly code.
  19. // If your compiler doesn't honour volatile parameters you'll have to write
  20. // inline assembly code.
  21. //
  22. // You should also read the "Macintosh AppleTalkĀ® Connections Programmer's Guide"
  23. // available from Apple.
  24.  
  25. #include <AppleTalk.h>
  26. #include "LAPEqu.h"
  27.  
  28. #include "StuTypes.h"
  29. #include "adev.h"
  30.  
  31. // *********************************************************************************
  32.  
  33. local char doGetAdev(u_long const pram, u_long volatile d2, u_char *volatile name);
  34. local void doSelAdev(u_long volatile pram, u_long const d2);
  35. local void doReSelAdev(u_long volatile pram, u_long const d2);
  36.  
  37. export void main(void)
  38.     {
  39.     asm        {
  40.     @0        move.l    a4, -(sp)        ; save A4
  41.             lea        @0, a4            ; set up global register
  42.             
  43.             cmpi.l    #GetADEV, D0    ; Is this a GetADEV call?
  44.             bne.s    @1                ; If not, try the next one
  45.             
  46.             move.l    a0, -(sp)        ; If yes,
  47.             move.l    d2, -(sp)        ; Push parameters on the stack
  48.             move.l    d1, -(sp)
  49.             bsr        doGetAdev        ; and make the call
  50.             move.l    (sp)+, d1
  51.             move.l    (sp)+, d2
  52.             move.l    (sp)+, a0
  53.             bra.s    @exit
  54.  
  55.     @1        cmpi.l    #SelectADEV, D0    ; Is this a SelectADEV call?
  56.             bne.s    @2                ; If not, try the next one
  57.  
  58.             move.l    d2, -(sp)        ; If yes,
  59.             move.l    d1, -(sp)        ; Push parameters on the stack
  60.             bsr        doSelAdev        ; and make the call
  61.             move.l    (sp)+, d1
  62.             move.l    (sp)+, d2
  63.             bra.s    @exit
  64.  
  65.     @2        cmpi.l    #ReSelADEV, D0    ; Is this a ReSelADEV call?
  66.             bne.s    @exit            ; If not, give up
  67.  
  68.             move.l    d2, -(sp)        ; If yes,
  69.             move.l    d1, -(sp)        ; Push parameters on the stack
  70.             bsr        doReSelAdev        ; and make the call
  71.             move.l    (sp)+, d1
  72.             move.l    (sp)+, d2
  73.  
  74.     @exit    move.l    (sp)+, a4        ; restore A4
  75.             }
  76.     }
  77.  
  78. // *********************************************************************************
  79.  
  80. enum { InterfaceActive = -1, InterfaceInactive = 0, NoMoreInterfaces = 1 };
  81.  
  82. local u_short num_ports;
  83.  
  84. local char doGetAdev(u_long const pram, u_long volatile d2, u_char *volatile name)
  85.     {
  86.     // If d2 is zero, then this is the first adev call, and we should do any
  87.     // necessary initialization. As part of that initialization I set the high
  88.     // order bytes d2 to be non-zero, so that on the next call I'll know that
  89.     // I've already done the initialization. The low byte (byte 0) of d2 contains
  90.     // a zero-based index to identify a particular port for adevs that support
  91.     // multiple ports (e.g. Printer Port and Modem Port) -- so we return zero
  92.     // the first time and increment it on subsequent calls. The choice of 0x00FFFF
  93.     // as the chosen "non-zero value" for the high order bytes is because there's
  94.     // a bug on Duos that makes them forget your chosen network selection when you
  95.     // put the Duo to sleep and when it wakes up again it reverts to LocalTalk.
  96.     // Putting 0xFFFF in the top word of the PRAM value seems to avoid the bug.
  97.     // Don't ask me why.
  98.     if (!d2)    
  99.         {
  100.         d2 = 0x00FFFF00;
  101.         // Do initialization here,
  102.         // eg. count how many ports are available
  103.         num_ports = 1;
  104.         }
  105.     else d2++;
  106.  
  107.     if ((d2 & 0xFF) >= num_ports) return(NoMoreInterfaces);
  108.  
  109.     // Give the name of the port identified by index (d2 & 0xFF)
  110.     name = "\pNone";
  111.     
  112.     // Wierd magic required by the Network Control Panel
  113.     if ((pram >> 8) == d2) return(InterfaceActive); else return(InterfaceInactive);
  114.     }
  115.  
  116. // *********************************************************************************
  117.  
  118. local void doSelAdev(u_long volatile pram, u_long const d2)
  119.     {
  120.     // User has clicked on one of our icons, identified by d2
  121.     // Stash this code in the high three bytes of the AppleTalk PRAM
  122.     // so we'll know which port to open in the atlk resource
  123.     pram = d2 << 8 | ADEV_ID;
  124.     }
  125.  
  126. // *********************************************************************************
  127.  
  128. local void doReSelAdev(u_long volatile pram, u_long const d2)
  129.     {
  130.     // User has clicked again on our already selected icon
  131.     // Can display dialog for options or configuration display here
  132.     pram = d2 << 8 | ADEV_ID;
  133.     }
  134.